STM32 RTC掉电不走时

您所在的位置:网站首页 4matic停止运行 低速 STM32 RTC掉电不走时

STM32 RTC掉电不走时

2024-06-20 00:16| 来源: 网络整理| 查看: 265

今天调试RTC使用LSI调试,后来改外部晶振不起振。可是使用内部晶振使用后备电池又不走时。网上找到答案

http://blog.chinaunix.net/uid-27106528-id-4288509.html

最初调试STM32的万年历,使用的是内部的 LSI晶振作为RTC晶振来源,发现有两个问题:      第一:由于LSI晶振频率大约在40KHZ附近,实际上会在30~60KHZ之间波动,导致计时不准,基本上一个小时会有1分钟左右的偏差。      第二: 由于LSI内部晶振,在断电的时候,并不在后备供电区域范围内,而外接的3.3V电池连接到VBAT上,只给后备供电区域供电,导致系统断电后,电池只能维持后备RTC的计数,并没有给LSI晶振供电(见下图所示:),导致RTC总是保持在断电之前的时间。虽然重新上电后又可以继续运行。但是需要重新校准了 。     最后使用了外界的32.768KHZ的外部LSE晶振作为RTC晶振来源,调试过程中发现,反复修改,问题和之前使用LSI没有区别。 后面仔细回想才发现了问题所在,因为调试过程中加了if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5)的判断,由于电池一直接到MCU上, 虽然反复的刷程序,都没有改变备份数据寄存器的值。而RTC的晶振来源一经确定,中途是不能改变的,除非全部复位备份域。 最后通过暂时取下电池(或暂时短路电池),又或者复位备份域,才成功重新设置为外部LSE晶振。时间精度的问题和断电RTC依旧运行的问题得到了解决。

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

结论:使用LSI掉电使用后备电池不能走时。要改用LSE要系统全掉电并重启,否则LSE无法就绪。

#include"RTC.h" Time sysTime; //是否使用外部晶振 #define USE_EXTERNEL_CRYSTAL void RTC_NVIC_Config(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn; //指定是RTC全局中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } void RTC_Configuration(void) { /* Enable PWR and BKP clocks */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); /* Allow access to BKP Domain */ PWR_BackupAccessCmd(ENABLE); if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5) { BKP_DeInit();//BKP寄存器全部设为缺省值 #ifdef USE_EXTERNEL_CRYSTAL RCC_LSEConfig(RCC_LSE_ON); //RCC打开了LSE时钟 while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==RESET);//等待LSE就绪,如果谐振不对,就会死在这里. RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);//RTC使用时钟源LSE #else RCC_LSICmd(ENABLE);// Enable the LSI OSC while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET); // Wait till LSI is ready RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);// Select the RTC Clock Source #endif RCC_RTCCLKCmd(ENABLE);// Enable RTC Clock RTC_WaitForSynchro();//RTC等待同步 RTC_WaitForLastTask();//等待就绪 RTC_ITConfig(RTC_IT_SEC, ENABLE); // 使能RTC秒中断 //RTC_SetPrescaler(32767);//RTC预分频,32768HZ RTC_SetPrescaler(40000);//RTC预分频,32768HZ RTC_WaitForLastTask(); BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);//往备份域寄存器中写一个特殊的字符 // SetDateTime((TagDateTime *)&DefaultSystime); //设置一个初始时间 PWR_BackupAccessCmd(DISABLE);//禁止RTC后备寄存器 RCC_ClearFlag(); //清除RCC重启标志 } else { #ifdef USE_EXTERNEL_CRYSTAL RCC_LSEConfig(RCC_LSE_ON); //RCC打开了LSE时钟 while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==RESET);//等待LSE就绪,如果谐振不对,就会死在这里. RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);//RTC使用时钟源LSE #else RCC_LSICmd(ENABLE);// Enable the LSI OSC while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);// Wait till LSI is ready RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); // Select the RTC Clock Source #endif // Enable RTC Clock RCC_RTCCLKCmd(ENABLE); RTC_WaitForSynchro();//RTC等待同步 //AdjustRtcTime();//配置系统时间,主要是考虑到断电重启如何恢复系统时间 RTC_ITConfig(RTC_IT_SEC, ENABLE); // 使能RTC秒中断 RTC_WaitForLastTask(); PWR_BackupAccessCmd(DISABLE);//禁止RTC后备寄存器 RCC_ClearFlag(); //清除RCC重启标志 } RTC_NVIC_Config(); }



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3